package net.takela.common.spring.filter;

import org.apache.tomcat.util.http.fileupload.IOUtils;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
 * @author baboy
 * create at 2023/1/22
 */
public class HttpRequestCachedServlet extends HttpServletRequestWrapper {
    private HttpServletRequest request;
    private ByteArrayOutputStream cachedOutputStream;
    /**
     * 
     */
    public HttpRequestCachedServlet(HttpServletRequest request) {
        super(request);
        this.request = request;
    }
    /**
     * 
     */
    public synchronized ServletInputStream getInputStream() throws IOException {
        if (this.cachedOutputStream == null) {
            this.cachedOutputStream = new ByteArrayOutputStream();
            IOUtils.copy(super.getInputStream(), this.cachedOutputStream);
        }

        ServletInputStream inputStream = new ContentCachedInputStream(this.cachedOutputStream);
        if (inputStream.markSupported()) {
            inputStream.reset();
        }

        return inputStream;
    }

    private class ContentCachedInputStream extends ServletInputStream {
        private ByteArrayInputStream is;
        private boolean isFinished = false;
    /**
     * 
     */
        public ContentCachedInputStream(ByteArrayOutputStream os) {
            this.is = new ByteArrayInputStream(os.toByteArray());
        }
    /**
     * 
     */
        public int read() throws IOException {
            int c = this.is.read();
            if (c == -1) {
                this.isFinished = true;
            }

            return c;
        }
    /**
     * 
     */
        public boolean isFinished() {
            return this.isFinished;
        }
    /**
     * 
     */
        public boolean isReady() {
            return true;
        }
    /**
     * 
     */
        public void setReadListener(ReadListener readListener) {
        }
    /**
     * 
     */
        public void close() throws IOException {
            this.is.close();
        }
    }
}
